import random
import socket
import struct
import KBEngine
import KBEDebug as log
import GlobalConst
import json
import time
import Utils

TIMER_TYPE_DESTROY = 0
TIMER_TYPE_LAYEGG = 1


class Avatar(KBEngine.Proxy):

    def __init__(self):
        KBEngine.Proxy.__init__(self)

        self.accountEntity = None
        self.destroyTimer = 0
        self.spaceKey = 0
        self.editLandKey = 0
        self.isWaitingDestroyCell = False
        self.layEggTimer = 0
        self.lastLogoutTime = 0

        log.DEBUG_MSG('Avatar::__init__ base dbid = %i' % (self.databaseID))

    # -------------------KBEngine method----------------------------
    def onClientEnabled(self):
        """
        该entity被正式激活为可使用，此时entity已经建立了client对应实体，可以在此创建它的cell部分
        """
        log.INFO_MSG("Avatar[%i].onClientEnabled entity enable." % self.id)
        self.ip = socket.inet_ntoa(struct.pack("=I", self.clientAddr[0]))

        # 断线重连回来后删除自动销毁实体的定时器
        if self.destroyTimer > 0:
            self.delTimer(self.destroyTimer)
            self.destroyTimer = 0
        if self.lastLogoutTime != 0:
            time_diff = time.time() - self.lastLogoutTime
            self.farm.createEggs(time_diff)
        self.rank.onAvtarRankEnable()
        self.client.onAvatarEnabled()
        self.farm.onAvatarEnabled()
        self.avatarOther.onAvatarEnabled()
        self.dailyRefresh()
        if self.layEggTimer == 0:
            # self.layEggTimer = self.addTimer((time.time() - self.lastLogoutTime) % 600, 600, TIMER_TYPE_LAYEGG)
            self.layEggTimer = self.addTimer((time.time() - self.lastLogoutTime) % 900, 900, TIMER_TYPE_LAYEGG)
        
        log.DEBUG_MSG(f'发送回调，更新信息')
        # 先刷新每日需要重置的数据，然后再更新登录时间
        # if self.playerId not in KBEngine.baseAppData['Lobby'].normal_group: # int(time.time()) - self.loginTime >= 7*24*3600 and
        self.loginTime = int(time.time())

        if self.playerId == 0:
            log.ERROR_MSG(f'Avatar.onClientEnabled playerId is zero: {self.databaseID} {self.databaseInterfaceName}')

        KBEngine.baseAppData['Lobby'].avatarEnterWorld(self, self.playerId)
        KBEngine.baseAppData['Lobby'].updateLogIn(self.playerId)
        log.DEBUG_MSG(f'avatar.onclientEnabled 结束')

    def onClientDeath(self):
        """
        KBEngine methods.
        entity丢失了客户端实体
        """
        log.DEBUG_MSG('Avatar[%i]::onClientDeath.' % self.id)
        self.destroyTimer = self.addTimer(60, 0, TIMER_TYPE_DESTROY)  # 60s后销毁avatar实体
        self.farm.lastInGameTime = int(time.time())
        self.farm.lastIsOffline = 1
        KBEngine.baseAppData['Lobby'].avatarLeaveWorld(self.playerId)


    def onTimer(self, tid, userArg):
        """
        引擎回调timer触发
        """
        if userArg == TIMER_TYPE_DESTROY:
            self.destroySelf()
        if userArg == TIMER_TYPE_LAYEGG:
            if self.destroyTimer > 0:
                self.farm.createEggsOnLine()
            else:
                self.client.onLayEggs()

    def onDestroy(self):
        """
        KBEngine method.
        如果这个函数在脚本中有实现，这个函数在调用Entity.destroy()后，在实际销毁之前被调用。
        这个函数没有参数。
        """
        log.DEBUG_MSG("Avatar[%i].onDestroy" % self.id)

        self.destroyAccount()

    def onGetCell(self):
        """
        entity的cell部分实体被创建成功
        """
        log.DEBUG_MSG(f'Avatar[{self.id}].onGetCell')
        spaceCell = self.getSpaceCell()
        if spaceCell is not None:
            spaceCell.onEnter(self.cell)

    def onLoseCell(self):
        """
        cell端销毁后c++层会调用到这里
        """
        log.DEBUG_MSG(f'Avatar[{self.id}].onLoseCell')
        if self.isWaitingDestroyCell is True:  # 如果是在销毁实体流程中遇到cell实体未销毁，则等到cell实体被销毁后继续销毁流程
            self.destroySelf()

    # ---------------------defined method-----------------------
    def destroySelf(self):
        log.DEBUG_MSG(f'Avatar[{self.id}]::destroySelf')

        if self.client is not None:
            return
        self.lastLogoutTime = time.time()  # 记录下线时间
        if self.layEggTimer > 0:#销毁下蛋计时器
            self.delTimer(self.layEggTimer)
            self.layEggTimer = 0
        # 如果帐号ENTITY存在，则也通知销毁它
        self.destroyAccount()

        if self.cell is not None and self.isWaitingDestroyCell is False:
            self.leaveSpace()
            self.isWaitingDestroyCell = True
            log.DEBUG_MSG(f'Avatar[{self.id}]::destroySelf destroyCellEntity')
            # 从base发送到cell，告诉c++层的cellapp销毁cell实体，cell实体被销毁后会调用到脚本层的onLoseCell方法
            self.destroyCellEntity()    # c++层通过发送数据包的方式，将销毁cell实体的操作发送到cellapp中
            return

        # 销毁base
        if self.isDestroyed is False:
            log.DEBUG_MSG(f'Avatar[{self.id}]::destroySelf finally')
            self.destroy()

    def destroyAccount(self):
        if self.accountEntity is not None:
            if self.accountEntity.isDestroyed is False:
                log.DEBUG_MSG(f'Avatar[{self.id}]::destroySelf, destroy accountEntity')
                self.accountEntity.activeAvatar = None
                self.accountEntity.destroy()
                self.accountEntity = None

    def createCell(self, spaceCell, spaceKey):
        """
        创建cell实体
        """
        log.DEBUG_MSG(f'Avatar[{self.id}].createCell {spaceKey}')
        if self.spaceKey == spaceKey and self.cell is not None:
            log.ERROR_MSG(f'createCell error.')
            return

        self.spaceKey = spaceKey
        self.createCellEntity(spaceCell)

    def dailyRefresh(self):
        """
        每日刷新
        """
        is_cross_day = Utils.isCrossDay(self.loginTime)
        if is_cross_day is False:
            return
        self.avatarOther.dailyRefresh()
        self.rank.dailyRefresh()
        self.task.resetDailyTask()
        #self.farm.dailyRefresh()

    def minuteRefresh(self):
        pass

    def reqCreateAvatar(self, role_type, role_name):
        # KBEngine.baseAppData['Lobby'].avatarLeaveWorld(self.playerId)
        # self.giveClientTo(self.accountEntity)
        # self.accountEntity.reqCreateAvatar(role_type, role_name)
        # self.accountEntity = None
        # self.destroySelf()

        for i in range(len(self.accountEntity.characters)):
            if self.accountEntity.characters[i]['state'] == 2:
                self.accountEntity.characters[i]['state'] = 0

        self.accountEntity.characters.append({
            'dbid': 0,
            'roleType': role_type,
            'nickName': role_name,
            'state': 2,
            'playerId': 0,
            'chapterId': 1,
            'level': 1
        })
        self.accountEntity.writeToDB()
        self.client.OnCreateNewAvatarSuccess()

    def selectAvatarGame(self, dbid):
        log.DEBUG_MSG(f'selectAvatarGame 0 {dbid} {self.accountEntity.characters}')
        for i in range(len(self.accountEntity.characters)):
            # 当前选中的
            if self.accountEntity.characters[i]['dbid'] == dbid:
                self.accountEntity.characters[i]['state'] = 2  # 当前角色为选中状态
            else:
                if self.accountEntity.characters[i]['state'] == 2:
                    self.accountEntity.characters[i]['state'] = 0
        self.accountEntity.writeToDB()
        log.DEBUG_MSG(f'selectAvatarGame 1 {dbid} {self.accountEntity.characters}')

        self.client.OnSelectAvatar()

    def delAvatar(self, dbid):
        for i in range(len(self.accountEntity.characters)):
            # 当前选中的
            if self.accountEntity.characters[i]['dbid'] == dbid:
                if self.accountEntity.characters[i]['state'] != 1:
                    self.accountEntity.characters[i]['state'] = 1  # 当前角色为删除状态
        self.accountEntity.writeToDB()
        self.client.OnDelAvatarSuccess(dbid)

    def updateNickName(self, nickName):
        if self.nickName != nickName:
            self.nickName = nickName
            if self.rank.groupId != 0:
                # 更新库中角色昵称
                KBEngine.baseAppData['Lobby'].updateNickName(self.playerId, self.rank.groupId, self.nickName)

    def updateHeadIcon(self, headImgUrl):
        if self.headImgUrl != headImgUrl:
            self.headImgUrl = headImgUrl
        if self.rank.groupId != 0:
            # 更新库中角色头像
            KBEngine.baseAppData['Lobby'].updateHeadImgUrl(self.playerId, self.rank.groupId, self.headImgUrl)

    def reqSeasonRank(self):
        KBEngine.baseAppData['Lobby'].reqSeasonRank(self)

    def reqGroupMemberInRank(self, group_id):
        log.DEBUG_MSG(f'reqGroupMemberInRank: {group_id}')
        KBEngine.baseAppData['Lobby'].loadGroupMemberInRank(self, group_id, 30)

    def updateUserId(self, user_id):
        log.DEBUG_MSG(f'updateUserId: {[self.playerId]} user_id:{user_id}')
        self.userId = user_id

    def setVip(self, vip):
        log.INFO_MSG(f'setVip: {[self.playerId]} vip: {vip}')
        self.vip = vip
        
    def reqTaskInfo(self):
        KBEngine.baseAppData['Lobby'].reqTaskInfo(self)
